﻿using System;
using System.Text;
using System.IO;
using System.Xml;
using System.Data;

namespace ZhuGe.Tools.XML
{
    /// <summary>
    /// 版权： Copyright by SEM IT Department
    /// 版本： 0.0.1
    /// 文件： XmlBook.Com.Sem.Tools.XmlDataBase.cs
    /// 目的： 提供将XML当作数据库处理的一些方法
    /// 作者： 欧阳云天 @2005-04-0Array
    /// 邮箱： outrace@soueast-motor.com
    /// 修改：
    /// </summary>
    public class XmlDataBase
    {
        #region 私有成员

        private string strDataFile = null;
        /// <summary>
        /// 数据集
        /// </summary>
        private DataSet myDs = null;
        /// <summary>
        /// 字符过滤数组 比如 "id=’1’ and userName=’trace’" 
        /// </summary>
        private string strFilter = null;
        /// <summary>
        /// 排序的字段 比如 "id desc,userName"
        /// </summary>
        private string strSort = null;
        /// <summary>
        /// 数据集合中的字段名集合
        /// </summary>
        private string[] strFields = null;
        /// <summary>
        /// 数据集合中的数据数组
        /// </summary>
        private string[] strData = null;
        /// <summary>
        /// 模板文件的全路径
        /// </summary>
        private string strTemplateFile = null;
        #endregion

        #region 公共属性
        /// <summary>
        /// 模板文件路径
        /// </summary>
        public string StrTemplateFile
        {
            set { this.strTemplateFile = value; }
            get { return this.strTemplateFile; }
        }
        /// <summary>
        /// 数据文件路径
        /// </summary>
        public string StrDataFile
        {
            set { this.strDataFile = value; }
            get { return this.strDataFile; }
        }
        /// <summary>
        /// 字符过滤数组
        /// </summary>
        public string StrFilter
        {
            set { this.strFilter = value; }
        }
        /// <summary>
        /// 排序的字段
        /// </summary>
        public string StrSort
        {
            set { this.strSort = value; }
        }
        /// <summary>
        /// 数据集合中的字段名
        /// </summary>
        public string[] StrFields
        {
            set { this.strFields = value; }
        }
        /// <summary>
        /// 数据集合中的数据数组
        /// </summary>
        public string[] StrData
        {
            set { this.strData = value; }
        }
        /// <summary>
        /// 数据集合，可以放在缓存供调用
        /// </summary>
        public DataSet MyDs
        {
            set { this.myDs = value; }
            get { return this.myDs; }
        }
        #endregion

        public XmlDataBase()
        {
            //
            // TODO: 提供将XML当作数据库处理的一些方法
            //
        }

        /// <summary>
        /// 取得XML文件的内容并填入DataSet
        /// </summary>
        private void Open()
        {
            try
            {
                this.myDs = new DataSet();
                FileStream fin;
                fin = new FileStream(this.strDataFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                this.myDs.ReadXml(fin);
                fin.Close();
            }
            catch (Exception ee)
            {
                Log log = new Log();
                log.StrUser = "系统";
                log.StrDepartment = "读取XML数据";
                log.StrFileName = "Com.Sem.Tools.XmlDataBase";
                log.StrDescription = ee.Message;
                log.WriteLog();
            }
        }

        /// <summary>
        /// 将操作结果写入XML
        /// </summary>
        private void Save()
        {
            try
            {
                this.myDs.WriteXml(this.strDataFile, XmlWriteMode.WriteSchema);
            }
            catch (Exception ee)
            {
                Log log = new Log();
                log.StrUser = "系统";
                log.StrDepartment = "保存XML数据";
                log.StrFileName = "Com.Sem.Tools.XmlDataBase";
                log.StrDescription = ee.Message;
                log.WriteLog();
            }
        }

        /// <summary>
        /// 取得特定的数据视图
        /// 一般在数据绑定的时候，我们可以很方便的生成供绑定的视图
        /// </summary>
        /// <returns>数据视图</returns>
        public DataView SelectView()
        {
            if (this.myDs == null) this.Open();

            DataView myDv = new DataView(this.myDs.Tables[0]);

            if (strFilter != null) myDv.RowFilter = this.strFilter;

            myDv.Sort = this.strSort;

            return myDv;
        }

        /// <summary>
        /// 取得特定的行
        /// 使用行的方式是因为有些时候，我们仅仅只需要某一行或多行记录
        /// 比如我们判断登陆的时候，只是需要某个ID的所在行，然后匹配它的密码项
        /// </summary>
        /// <returns>各行数据</returns>
        public DataRow[] SelectRows()
        {
            if (this.myDs == null) this.Open();
            DataRow[] myRows = myDs.Tables[0].Select(this.strFilter);
            return myRows;
        }

        /// <summary>
        /// 往XML当中插入一条数据
        /// </summary>
        /// <returns>操作是否成功</returns>
        public bool Insert()
        {
            if (this.myDs == null) this.Open();

            try
            {
                DataRow newRow = myDs.Tables[0].NewRow();

                for (int i = 0; i < this.strFields.Length; i++)
                {
                    newRow[this.strFields[i]] = this.strData[i];
                }

                myDs.Tables[0].Rows.Add(newRow);
                this.Save();
                return true;
            }
            catch (Exception ee)
            {
                Log log = new Log();
                log.StrUser = "系统";
                log.StrDepartment = "写入XML数据";
                log.StrFileName = "Com.Sem.Tools.XmlDataBase";
                log.StrDescription = ee.Message;
                log.WriteLog();
                return false;
            }
        }

        /// <summary>
        /// 更新数据,这个时候要确保strFields 与 strData 两个数组的维数一致
        /// </summary>
        /// <returns>是否更新成功</returns>
        public bool Update()
        {
            if (this.myDs == null) this.Open();

            try
            {
                DataRow[] editRow = myDs.Tables[0].Select(this.strFilter);

                for (int j = 0; j < editRow.Length; j++)
                {
                    for (int i = 0; i < this.strFields.Length; i++)
                    {
                        editRow[j][this.strFields[i]] = this.strData[i];
                    }
                }
                this.Save();
                return true;
            }
            catch (Exception ee)
            {
                Log log = new Log();
                log.StrUser = "系统";
                log.StrDepartment = "更新XML数据";
                log.StrFileName = "Com.Sem.Tools.XmlDataBase";
                log.StrDescription = ee.Message;
                log.WriteLog();
                return false;
            }
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <returns>是否删除成功</returns>
        public bool Delete()
        {
            if (this.myDs == null) this.Open();

            try
            {
                DataRow[] editRow = myDs.Tables[0].Select(this.strFilter);
                for (int i = 0; i < editRow.Length; i++)
                {
                    editRow[i].Delete();
                }
                this.Save();
                return true;
            }
            catch (Exception ee)
            {
                Log log = new Log();
                log.StrUser = "系统";
                log.StrDepartment = "删除XML数据";
                log.StrFileName = "Com.Sem.Tools.XmlDataBase";
                log.StrDescription = ee.Message;
                log.WriteLog();
                return false;
            }
        }

        /// <summary>
        /// 根据一个模板，新建一个XML文件（前提是必须有一个模板文件、并确定目标文件路径）
        /// </summary>
        /// <returns>写入是否成功</returns>
        public bool Create()
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                XmlTextReader reader = new XmlTextReader(this.strTemplateFile);
                doc.Load(reader);
                XmlElement member;
                XmlNode root = doc.DocumentElement;

                for (int i = 0; i < this.strFields.Length; i++)
                {
                    member = doc.CreateElement(strFields[i].ToString());
                    member.InnerText = this.strData[i].ToString();
                    root.AppendChild(member);
                }

                XmlTextWriter xmlWriter = new XmlTextWriter(this.strDataFile, null);
                xmlWriter.Formatting = Formatting.Indented;
                doc.Save(xmlWriter);

                xmlWriter.Close();
                reader.Close();
                return true;
            }
            catch (Exception ee)
            {
                Log log = new Log();
                log.StrUser = "系统";
                log.StrDepartment = "新建XML数据";
                log.StrFileName = "Com.Sem.Tools.XmlDataBase";
                log.StrDescription = ee.Message;
                log.WriteLog();
                return false;
            }
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Clear()
        {
            if (this.myDs != null)
            {
                this.myDs.Dispose();
            }
        }
    }
}
